package Noyau;

import java.awt.geom.Point2D;

public class Tapis extends CheminBagage
{
	private double vitesse = 0;

	public double getVitesse()  {
		return this.vitesse;
	}

	public void setVitesse(double value)
	{
		this.vitesse = value;
	}

	@Override
	public boolean PeutAjouterBagage(Bagage newBagage)
	{
		// We want to make sure that we have enough room left to fit the new bagage.
		// We retrieve the last bagage and compute it's position.
		if (this.bagages.size() > 0)
		{
			Bagage lastBagage = this.bagages.get(this.bagages.size() - 1);
			double position = lastBagage.getPosition() * (this.getSize() - lastBagage.getSize());

			if ((position - (lastBagage.getSize() / 2)) <= (newBagage.getSize() / 2))
			{
				return false;
			}
		}

		return true;
	}

	@Override
	public boolean AjouterBagage(Bagage newBagage) {		
		if (!this.PeutAjouterBagage(newBagage))
		{
			return false;
		}

		// Otherwise, we add the bagage to the list.
		newBagage.setPosition(0);
		this.CreerBagage(newBagage);

		return true;
	}

	@Override
	public void TickHorloge() {
		// We retrieve our size.
		double size = this.getSize();

		// For each bagage (sorted by highest position, FIFO), we try to
		// make them move, if it's possible.		
		int index = 0;
		while (index < this.bagages.size())
		{
			// We retrieve the bagage at Index index.
			Bagage bagage = this.bagages.get(index);

			// We compute the new position of this bagage.
			double position = bagage.getPosition();
			position += this.vitesse / size;			

			if (position > 1)
			{
				// If we have no sortie, we stop the tapis.
				if (this.sortie == null)
				{
					break;
				}

				// If the bagage is out of the tapis, we try to give it to the sortie.
				if (!this.sortie.AjouterBagage(bagage))
				{
					break;
				}

				this.bagages.remove(bagage);
			}
			else
			{
				// We make sure we have enough space for the bagage.
				if (((1 - position) * size) < bagage.getSize() && this.sortie != null && !this.sortie.PeutAjouterBagage(bagage))
				{
					break;
				}

				// We update the position of the bagage.				
				bagage.setPosition(position);

				index++;	
			}
		}

		this.setChanged();
		this.notifyObservers();
	}

	@Override
	public Point2D getCenter()
	{
		if (this.entree == null)
		{
			return this.getOrigine();
		}

		double x = (this.entree.getOrigine().getX() + this.getOrigine().getX()) / 2;
		double y = (this.entree.getOrigine().getY() + this.getOrigine().getY()) / 2;

		return new Point2D.Double(x, y);
	}

	@Override
	public double getSize()
	{
		// If we have no entree, we return a length of 0.
		if (this.entree == null)
		{
			return 0;
		}

		// Otherwise, we calculate our length using the entree's origine point.
		double diffX = this.origine.getX() - this.entree.getOrigine().getX();
		double diffY = this.origine.getY() - this.entree.getOrigine().getY();

		return Math.sqrt(Math.pow(diffX, 2) + Math.pow(diffY, 2));
	}

	@Override
	public int getZBuffer()
	{
		return 0;
	}
}
